package com.miniboy.imageloader;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.util.Log;
import android.widget.ImageView;

import com.miniboy.imageloader.cache.impl.DishCahce;
import com.miniboy.imageloader.cache.impl.MemoryCahce;
import com.miniboy.imageloader.config.ImageOptions;
import com.miniboy.imageloader.domain.LoadResult;
import com.miniboy.imageloader.util.HttpUtil;
import com.miniboy.imageloader.util.MD5Util;
import com.miniboy.imageloader.util.NetUtil;

/**
 * 作者 ${郭鹏飞}.<br/>
 */
public class ImageLoader {

    private static final String TAG = ImageLoader.class.getSimpleName();
    private static ImageLoader instance = null;

    private Context mContext;

    /**
     * 内存缓冲
     */
    private MemoryCahce mMemoryCache;
    /**
     * 磁盘缓冲
     */
    private DishCahce mDiskCache;

    /**
     * 网络加载图片的工具类
     */
    private HttpUtil mHttpUtil;

    /**
     * 加载图片配置
     */
    private ImageOptions mImageOptions;
    /**
     * 显示图片的ImageView
     */
    private ImageView mImageView;
    /**
     * 图片下载地址
     */
    private String mUrl;

    private ImageLoader(Context context) {
        mContext = context;
    }

    public static ImageLoader getInstance(Context context) {
        if (instance == null) {
            synchronized (ImageLoader.class) {
                if (instance == null) {
                    instance = new ImageLoader(context);
                }
            }
        }
        return instance;
    }

    public Context getContext() {
        return mContext;
    }

    public MemoryCahce getMemoryCache() {
        if (mMemoryCache == null) {
            throw new NullPointerException("请调用init()对MemoryCache进行初始化");
        }
        return mMemoryCache;
    }

    public DishCahce getDiskCache() {
        if (mDiskCache == null) {
            throw new NullPointerException("请调用init()对DiskCache进行初始化");
        }
        return mDiskCache;
    }

    public ImageOptions getImageOptions() {
        if (mImageOptions == null) {
            throw new NullPointerException("请调用init()对ImageOptions进行初始化");
        }
        return mImageOptions;
    }

    public ImageLoader init(ImageOptions imageOptions) {
        if (imageOptions == null) {
            throw new NullPointerException("ImageOptions 为空");
        }
        mImageOptions = imageOptions;
        mMemoryCache = new MemoryCahce();
        mDiskCache = new DishCahce(mContext, imageOptions.mDiskMaxSize);
        mHttpUtil = HttpUtil.getInstance();
        return this;
    }

    public ImageLoader resetOptions(ImageOptions options) {
        mImageOptions = options;
        return this;
    }

    public ImageLoader into(ImageView imageView) {
        mImageView = imageView;
        return this;
    }

    public ImageLoader url(String url) {
        this.mUrl = url;
        return this;
    }

    /**
     * 加载图片
     */
    public synchronized void load() {
        if (mImageOptions == null) {
            throw new NullPointerException("请调用init()进行初始化");
        }
        if (mImageView == null) {
            throw new NullPointerException("请调用into()进行初始化ImageView");
        }
        Bitmap bitmap;
        // 设置默认占位图
        if (TextUtils.isEmpty((String)mImageView.getTag())) {
            bitmap = BitmapFactory.decodeResource(mContext.getResources(),
                    mImageOptions.mPlaceBitmapId);
            mImageView.setImageBitmap(bitmap);
        }
        if (TextUtils.isEmpty(mUrl)) { // 空下载地址设置显示图片
            Log.w(TAG, ">>>>>>> " + "空地址" + " <<<<<<");
            bitmap = BitmapFactory.decodeResource(mContext.getResources(),
                    mImageOptions.mEmptyUrlBitmapId);
            mImageView.setImageBitmap(bitmap);
            return;
        }
        String key = MD5Util.format(mUrl);
        if (TextUtils.isEmpty(key)) { // 处理url失败 直接从网络获取图片
            downBitmapFromNetwork();
            return;
        }
        bitmap = mMemoryCache.get(key); // 通过key从内存缓冲里面获取数据
        if (bitmap == null) {
            bitmap = mDiskCache.get(key); // 通过key从磁盘缓冲里面获取数据
            if (bitmap == null) {
                mImageView.setTag(mUrl);
                downBitmapFromNetwork();
            } else {
                Log.w(TAG, ">>>>>>> " + "图片来源磁盘缓冲" + " <<<<<<");
                mImageView.setImageBitmap(bitmap); // 从磁盘里面得到图片
                // 判断是否需要内存缓冲 需要则将数据写到内存缓存中
                if (mImageOptions.mCacheType == ImageOptions.TYPE_ALL_CACHE) {
                    mMemoryCache.put(key, bitmap);
                }
            }
        } else {
            Log.w(TAG, ">>>>> " + "图片来源内存缓冲" + " <<<<<<");
            mImageView.setImageBitmap(bitmap); // 从内存里面得到图片
        }
    }

    /**
     * 从网络下载图片
     */
    private void downBitmapFromNetwork() {
        if (NetUtil.isNetWorkCanUse(mContext)) { // 有网络
            mHttpUtil.execute(new HttpUtil.DownImageTask(
                    mUrl, mImageOptions.mWidth, mImageOptions.mHeight, mImageView
            ), new HttpUtil.AsyncDownImageHandler() {
                @Override
                public void successed(LoadResult loadResult) {
                    Log.w(TAG, ">>>>>>> " + "图片下载成功" + " <<<<<<");
                    ImageView imageView = loadResult.getImageView();
                    String url = loadResult.getUrl();
                    Bitmap bitmap = loadResult.getBitmap();
                    if (imageView == null || TextUtils.isEmpty(url) ||
                            bitmap == null) {
                        return;
                    }
                    if (imageView.getTag().equals(url)) {
                        imageView.setImageBitmap(bitmap);
                    }
                    doCache(url, bitmap);
                }

                @Override
                public void failed(int errorCode, ImageView imageView, String url) {
                    Log.w(TAG, ">>>>>> " + errorCode + " <<<<<<<");
                    if (imageView.getTag().equals(url)) {
                        Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),
                                mImageOptions.mFailedBitmapId);
                        mImageView.setImageBitmap(bitmap);
                    }
                }
            });
        } else { // 没有网络 显示默认展位图
            Log.w(TAG, ">>>>>>> " + "没有网络" + " <<<<<<");
            Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),
                    mImageOptions.mNoNetworkBitmapId);
            mImageView.setImageBitmap(bitmap);
        }
    }

    /**
     * 进行缓冲处理
     *
     * @param url    key
     * @param bitmap value
     */
    private void doCache(String url, Bitmap bitmap) {
        String key = MD5Util.format(url);
        if (TextUtils.isEmpty(key)) {
            return;
        }
        switch (mImageOptions.mCacheType) {
            case ImageOptions.TYPE_NO_CACHE:
                Log.w(TAG, ">>>>>>> " + "没有缓冲" + " <<<<<<");
                break;
            case ImageOptions.TYPE_MEMORY_CACHE:
                Log.w(TAG, ">>>>>>> " + "内存缓冲" + " <<<<<<");
                mMemoryCache.put(key, bitmap);
                break;
            case ImageOptions.TYPE_DISK_CACHE:
                Log.w(TAG, ">>>>>>> " + "磁盘缓冲" + " <<<<<<");
                mDiskCache.put(key, bitmap);
                break;
            case ImageOptions.TYPE_ALL_CACHE:
            default:
                Log.w(TAG, ">>>>>>> " + "双缓冲" + " <<<<<<");
                mMemoryCache.put(key, bitmap);
                mDiskCache.put(key, bitmap);
                break;
        }
    }

}
